package net.rlair.sbdemo.service;

import net.rlair.sbdemo.dao.mybatis.bootmapper.UserMapper;
import net.rlair.sbdemo.entity.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Random;

/**
 * 使用Mybatis+默认连接池方式创建多个事务，设置隔离级别为read uncommitted，要求如下：
 * 1）模拟出现脏读的情况；
 * 2）代码放在service中，已IsolationLevel+开发姓名命名.
 *
 * @author yaoyi
 */
@Service
public class IsolationLevelYaoyi {
    @Resource
    private UserMapper userMapper;

    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public void updateUserEx(int id) {
        System.out.println(Thread.currentThread().getName() + "---查看用户名:" + selectById(id).getName());
        User user = new User();
        user.setId(id);
        user.setUpdated(new Date());
        user.setName("IsolationLevelUncommitted");
        //更新用户数据
        userMapper.updateNameById(user);
        System.out.println(Thread.currentThread().getName() + "---修改用户名为IsolationLevelUncommitted,事务未提交");
        //未提交，模拟脏读
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //回滚事务
        throw new RuntimeException("回滚事务，模拟脏读");
    }

    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public User selectById(int id) {
        final User user = userMapper.selectById(id);
        return user;
    }

    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public void selectAndUpdate(int id) {
        User user1 = selectById(id);
        System.out.println(Thread.currentThread().getName() + "---查看用户名:" + user1.getName());
        if ("IsolationLevelUncommitted".equals(user1.getName())) {
            User user = new User();
            user.setId(id);
            user.setUpdated(new Date());
            user.setName("IsolationLevelUpdate");
            //更新用户数据
            userMapper.updateNameById(user);
            System.out.println(Thread.currentThread().getName() + "---修改用户名为IsolationLevelUpdate");
        }
    }

    public User addUser() {
        User user = new User();
        user.setId(new Random().nextInt());
        user.setName("IsolationLevelTest");
        user.setPassword("psd");
        user.setCreated(new Date());
        user.setUpdated(new Date());
        int i = userMapper.addUser(user);
        System.out.println(i);
        return user;
    }

}
